/**********************************************************************
 Name:  DailyPlanControl
 Purpose:Trad 医院拜访拜访地图相关数据处理                                                            
-------                                                             
======================================================
History                                                            
-------                                                            
VERSION    AUTHOR                  DATE                 DETAIL                                
   1.0 -        huangxiaojiang       03/23/2011         Create  
   1.1-         huangxiaojiang       04/08/2011         Modified,增加了开始结束时间，实际拜访用开始时间升序排序
   2.0          huangxiaojiang        04/11/2011        Modified,把科内会或妈妈班记录形成的拜访也显示在实际路线，不显示在计划路线
*********************************** ************************************/
public with sharing class DailyPlanControl{

      //Variables
      
     // Constructors
     public  DailyPlanControl(ApexPages.StandardController controller){
         
      }

      // getter & setter
      public Date startDate{
          get;
          set;
      }
      
      public list<CallPlan__c>  lstCP{
          get;
          set;
      }
      public MonthlyCallPlan__c MCP{
          get;
          set;
      }
      
      
      public string MCPId{
          get;
          set;
      }
      
      public string PlanAddress{
          get;
          set;
      }
      
      public string PlanHospitalNames{
          get;
          set;
      }
      public string VisitAddress{
          get;
          set;
      }
      public string VisitHospitalNames{
          get;
          set;
      }
      public string ExceptionArray{
          get;
          set;
      }
      public string RangeValues{
          get;
          set;
      }
      public string PlanOrder{
          get;
          set;
      }
      public string VisitOrder{
          get;
          set;
      }
      public string PlanStatus{
          get;
          set;
      }
      
      public string HospitalAddress{
          get;
          set;
      }
      //methods
      
        /*
          1.日期变化时,返回指定日期的callPlan列表
          2.根据当前callPlan列表向页面输出地图路线显示需要的信息
      */
      public PageReference findPlanList(){
          outputMapData();
          
          return null;
      }
      
        /*
          1.页面首次加载，返回当天的callPlan列表
          2.根据当前callPlan列表向页面输出地图路线显示需要的信息
      */
      public PageReference onloadAction(){
          
          if(MCPId!=null){
                MCP=new  MonthlyCallPlan__c(id=MCPId);                          
          }else{
                MCP=new  MonthlyCallPlan__c(id=System.currentPageReference().getParameters().get('id'));         
          }
          MCP.DefaultDate__c=date.today();
          
          outputMapData();
              
          return null;
      }
      
      //更改地图显示所需要的属性
      private void outputMapData(){
         
         //查询特定日期的call plan,不包含医院活动
         lstCP=[select id,HospitalId__c,Name,CallPlanDate__c,Hospitalclass__c,HCP__c,HCPclass__c,HCPDepartment__c,CallPurpose__c,CallExecutionstatus__c,PlanType__c,
                       Hospital__c,Lat__c,Lon__c,IsException__c,DevRange__c from CallPlan__c where CallPlanDate__c=:MCP.DefaultDate__c
                       and  Monthly_Call_Plan__c=:MCP.id and ActivityId__c=null  order by Hospital__c asc];
        
        //增加科内会或妈妈班记录信息 
        list<recordtype> lstRT=new list<recordtype>();
        id IdKNH;//科内会的recordtype的Id
        id IdMMB;//妈妈班的recordtype的Id 
        lstRT=[select id,DeveloperName from recordtype where sobjecttype=:'CallPlan__c' and ( DeveloperName=:'Pclass' or DeveloperName=:'PS')];
        for(recordtype rt:lstRT){
            if(rt.DeveloperName=='Pclass'){
                IdMMB=rt.id;
            }else{
                if(rt.DeveloperName=='PS'){
                    IdKNH=rt.id;
                }
            }
        }
       
        //医院拜访记录,妈妈班或科内会活动记录                 
        list<CallPlan__c> lstCPVisit=[select id,HospitalId__c,Name,CallPlanDate__c,Hospitalclass__c,HCP__c,HCPclass__c,HCPDepartment__c,CallPurpose__c,CallExecutionstatus__c,PlanType__c,
                       Hospital__c,Lat__c,Lon__c,IsException__c,DevRange__c,ActivityId__c,RecordTypeId,StartTime__c from CallPlan__c where CallPlanDate__c=:MCP.DefaultDate__c
                       and  Monthly_Call_Plan__c=:MCP.id and (CallExecutionstatus__c='是' or (RecordTypeId=:IdMMB or RecordTypeId=:IdKNH)) order by StartTime__c asc];
                                  
         list<CallPlan__c> lstCP2 =new list<CallPlan__c>();
         list<CallPlan__c> lstCPVisit2 =new list<CallPlan__c>();
         //相对计划的实际拜访数据，筛选计划内的数据不管有没有拜访坐标
         list<CallPlan__c> lstCPVisitPlan =new list<CallPlan__c>();
                          
         //计划路线相同医院去重
         list<CallPlan__c> lCPTemp=new list<CallPlan__c>();
         for(integer i=0;i<lstCP.size();i++){
             if(lstCP[i].PlanType__c=='计划内'){
                 lCPTemp.add(lstCP[i]);
             }
          }

         set<id> setHpId=new set<id>();
         integer iIndex=0;                      
         for(integer i=0;i<lCPTemp.size();i++){
             iIndex=i;
             for(integer j=i+1;j<lCPTemp.size();j++){
                 if(lCPTemp[i].HospitalId__c==lCPTemp[j].HospitalId__c){
                     iIndex=j;
                 }
             }
             if(!setHpId.contains(lCPTemp[iIndex].HospitalId__c)){                      
                  lstCP2.add(lCPTemp[iIndex]);
                  setHpId.add(lCPTemp[iIndex].HospitalId__c);                                                           
             }                                      
        }
        lCPTemp.clear();

         //实际路线相同医院去重,相同医院取时间较早的，如果同一个医院既有计划内（必须有拜访坐标）又有计划外只显示计划内坐标
         setHpId.clear();                       
         for(integer i=0;i<lstCPVisit.size();i++){      
             iIndex=i;
             //计划内或计划外记录
             if(lstCPVisit[i].ActivityId__c==null){            
               for(integer j=i+1;j<lstCPVisit.size();j++){
                 if(lstCPVisit[i].HospitalId__c==lstCPVisit[j].HospitalId__c){
                     iIndex=i;
                     if(lstCPVisit[i].PlanType__c=='计划外'&&lstCPVisit[j].PlanType__c=='计划内'&&lstCPVisit[j].lat__c!=null&&lstCPVisit[j].lon__c!=null){
                         iIndex=j;
                     }
                 }
             }
             if(!setHpId.contains(lstCPVisit[iIndex].HospitalId__c)){
                 if(lstCPVisit[iIndex].lat__c!=null&&lstCPVisit[iIndex].lon__c!=null){
                       lstCPVisit2.add(lstCPVisit[iIndex]);
                       setHpId.add(lstCPVisit[iIndex].HospitalId__c);                     
                 }                                            
             }                 
          }else{//妈妈班或科内会记录直接放到实际拜访路线
              if(lstCPVisit[iIndex].lat__c!=null&&lstCPVisit[iIndex].lon__c!=null){
                   lstCPVisit2.add(lstCPVisit[iIndex]);   
              }                            
          }
       }
       //把实际拜访记录按时间升序排列,如果实际路线同一个医院既有计划内又有计划外，只显示计划内，此时计划内执行时间很有可能比计划外晚
       //list<CallPlan__c> lstCPVisit2Order=new list<CallPlan__c>();
       CallPlan__c oCPTemp=new CallPlan__c();
       integer iOrder=0;
       for(integer i=0;i<lstCPVisit2.size()-1;i++){
           iOrder=i;
           for(integer j=i+1;j<lstCPVisit2.size();j++){
               if(lstCPVisit2[j].StartTime__c!=null&&lstCPVisit2[iOrder].StartTime__c!=null){
                   if(lstCPVisit2[j].StartTime__c<lstCPVisit2[iOrder].StartTime__c){
                       iOrder=j;
                   }               
               }
           }
           if(i!=iOrder){
               oCPTemp=lstCPVisit2[iOrder];
               lstCPVisit2[iOrder]=lstCPVisit2[i];
               lstCPVisit2[i]=oCPTemp;
           }
       }
       
         
         //筛选实际拜访数据计划内拜访数据
         setHpId.clear();                       
         for(integer i=0;i<lstCPVisit.size();i++){
             //选择非妈妈班科内会，而且是计划内拜访记录
             if(lstCPVisit[i].ActivityId__c==null&&lstCPVisit[i].PlanType__c=='计划内'){
                 if(!setHpId.contains(lstCPVisit[i].HospitalId__c)){
                     lstCPVisitPlan.add(lstCPVisit[i]);
                     setHpId.add(lstCPVisit[i].HospitalId__c);
                 }
             }
         }      
                    
         
                            
          string strTemp1='';
          string strTemp2='';
          string strTemp3='';
          string strTemp4='';
          string strTemp5='';
          string strTemp6='';
          string strTemp9='';
          
          //实际拜访路线
         map<id,Hospital__c> mapHPVisit=new map<id,Hospital__c>(); 
         if(lstCPVisit2.size()>0){ 
              setHpId.clear();
              for(CallPlan__c cp:lstCPVisit2){
                  if(cp.ActivityId__c==null){
                       setHpId.add(cp.HospitalId__c);
                  }    
              }
              
              mapHPVisit=new map<id,Hospital__c>((list<Hospital__c>)[select id,name,Lat__c,Lon__c,adress__c from Hospital__c where id in:setHpId]);
              Hospital__c objHP=new Hospital__c();         
              CallPlan__c objCP=new CallPlan__c();
              Hospital__c objHP1=new Hospital__c();         
              CallPlan__c objCP1=new CallPlan__c();
              double dBasePoint=0.0003;
              double dIncreasePoint=0.0002;
              integer iRate=0;
              integer iRate1=0;                            
              
              for(integer i=0;i<lstCPVisit2.size();i++){              
                  objCP=lstCPVisit2[i];
                  //是医院活动才需要获取医院信息
                  if(objCP.ActivityId__c==null&&objCP.HospitalId__c!=null){
                      objHP=mapHPVisit.get(objCP.HospitalId__c); 
                  }
                  
                  //不同医院或医院拜访记录，有相同坐标点是经度偏移处理：偏移基数0.0003，相同递增0.0002
                  //偏移拜访活动坐标
                  for(integer j=i;j<lstCPVisit2.size();j++){
                      objCP1=lstCPVisit2[j];
                      if(objCP.lat__c!=null&&objCP.lon__c!=null&&objCP1.lat__c!=null&&objCP1.lon__c!=null){
                          if(objCP.lat__c==objCP1.lat__c&&objCP.lon__c==objCP1.lon__c){
                              objCP1.lon__c=string.valueOf(double.valueOf(objCP1.lon__c)+dBasePoint+iRate*dIncreasePoint);
                              iRate++;                         
                          }
                      }
                      //偏移医院坐标
                      if(objCP1.ActivityId__c==null&&objCP1.HospitalId__c!=null){
                          objHP1=mapHPVisit.get(objCP1.HospitalId__c); 
                      }
                      if(objHP!=null&&objHP1!=null){
                          if(objHP.lat__c!=null&&objHP.lon__c!=null&&objHP1.lat__c!=null&&objHP1.lon__c!=null){
                              if(objHP.lat__c==objHP1.lat__c&&objHP.lon__c==objHP1.lon__c){
                                  objHP1.lon__c=string.valueOf(double.valueOf(objHP1.lon__c)+dBasePoint+iRate1*dIncreasePoint);
                                  iRate1++;                                    
                              }
                          }
                      }                     
                  }
              //复位    
              iRate=0;
              iRate1=0;
                      
              //医院活动记录
              objCP=lstCPVisit2[i];
              if(objCP.ActivityId__c!=null){
                  strTemp3+=objCP.Lat__c+','+objCP.Lon__c+';';
                  if(objCP.RecordTypeId==IdMMB){//妈妈班记录
                      strTemp4+='妈妈班;';
                  }else{//科内会记录
                       strTemp4+='科内会;';   
                  }                  
                 strTemp5+='3;';//医院活动赋值3 
                 strTemp6+=objCP.DevRange__c+';';                       
              }else{//医院拜访记录
                  objHP=mapHPVisit.get(objCP.HospitalId__c); 
                  if(objHP!=null){
                       //医院地址赋值
                      if(HospitalAddress==null||HospitalAddress==''){
                           HospitalAddress=objHP.adress__c;
                      }                  
                      if(objHP.Lat__c!=null&&objHP.Lon__c!=null){                          
                          strTemp4+=objHP.name+';';
                          strTemp5+=objCP.IsException__c+';'; 
                          strTemp6+=objCP.DevRange__c+';'; 
                             
                          if(objCP.IsException__c==0){
                              string strLat=string.valueOf(double.valueOf(objHP.Lat__c)+0.0005);//正常拜访经度统一偏移0.0005度
                              strTemp3+=strLat+','+objHP.Lon__c+';';
                          }else{
                              strTemp3+=objCP.Lat__c+','+objCP.Lon__c+';';
                          }                            
                      }else{
                          //当前拜访有数据，医院没数据
                          if(objCP.Lat__c!=null&&objCP.Lon__c!=null){
                              strTemp4+=objHP.name+';';
                              strTemp5+='0;'; 
                              strTemp6+='0;'; 
                              strTemp3+=objCP.Lat__c+','+objCP.Lon__c+';';                                
                          }
                   
                      }                  
                  }

             
              }                                           
          }               
        }
                               
         //计划路线
         //计划路线如果不同医院有相同坐标，经度偏移：偏移基数0.0003，相同递增0.0002
         if(lstCP2.size()>0){
              setHpId.clear();
              for(CallPlan__c cp:lstCP2){                  
                  setHpId.add(cp.HospitalId__c);
              }
              map<id,Hospital__c> mapHP2Plan=new map<id,Hospital__c>((list<Hospital__c>)[select id,name,Lat__c,Lon__c from Hospital__c where id in:setHpId]);
              Hospital__c hp1=new Hospital__c();
              Hospital__c hp2=new Hospital__c();
              CallPlan__c cp1=new CallPlan__c();
              double dBasePoint=0.0003;
              double dIncreasePoint=0.0002;
              integer iRate=0;
                            
              for(integer i=0;i<lstCP2.size();i++){
                  cp1=lstCP2[i];
                  hp1=mapHP2Plan.get(cp1.HospitalId__c);
                  
                  if(hp1!=null){
                      if(hp1.lat__c!=null&&hp1.lon__c!=null){
                          for(integer j=i;j<lstCP2.size();j++){
                             cp1=lstCP2[j];
                             hp2=mapHP2Plan.get(cp1.HospitalId__c);
                             if(hp2!=null){
                                 if(hp2.lat__c!=null&&hp2.lon__c!=null){
                                     if(hp1.id!=hp2.id&&hp1.lat__c==hp2.lat__c&&hp1.lon__c==hp2.lon__c){
                                         hp2.lon__c=string.valueOf(double.valueOf(hp2.lon__c)+dBasePoint+iRate*dIncreasePoint);
                                         iRate++;                                                
                                     }
                                 }
                             } 
                          }
                      }
                  }
              iRate=0;//复位    
              }             
         }

         
          string strPlanStatus='';                  
        //计划已拜访医院
         map<id,Hospital__c> mapHPVisitPlan=new map<id,Hospital__c>();
          if(lstCPVisitPlan.size()>0){
              setHpId.clear();
              for(CallPlan__c cp:lstCPVisitPlan){                  
                  setHpId.add(cp.HospitalId__c);
              }
             mapHPVisitPlan=new map<id,Hospital__c>((list<Hospital__c>)[select id,name,Lat__c,Lon__c,ADRESS__C
                  from Hospital__c where id in:setHpId]);         
          }
         
        //计划没拜访过的医院     
         list<CallPlan__c> lCPActual=new list<CallPlan__c>();//存放计划内没拜访过的医院
         for(CallPlan__c cp:lstCP2){
             if(cp.CallExecutionstatus__c=='否'||cp.CallExecutionstatus__c==null){
                lCPActual.add(cp); 
             }
         }
         
         //如果实际拜访医院存在于计划路线的未拜访记录中，删除计划路线的这个医院记录
         for(CallPlan__c cp:lstCPVisitPlan){
             for(integer i=0;i<lCPActual.size();i++){
                 if(cp.HospitalId__c==lCPActual[i].HospitalId__c){
                     lCPActual.remove(i);
                 }
             }
         }
 
         map<id,Hospital__c> mapHPPlanNoVisit=new  map<id,Hospital__c>();      
         if(lCPActual.size()>0){
              setHpId.clear();
              for(CallPlan__c cp:lCPActual){
                  setHpId.add(cp.HospitalId__c);
              }
              mapHPPlanNoVisit=new map<id,Hospital__c>((list<Hospital__c>)[select id,name,Lat__c,Lon__c,ADRESS__C
                 from Hospital__c where id in:setHpId]);                
         }
       
       //生成计划路线  
       if(lstCP2.size()>0){
           Hospital__c objHP=new Hospital__c();
           CallPlan__c objCP=new CallPlan__c();         
           for(integer i=0;i<lstCP2.size();i++){
               objCP=lstCP2[i];       
                objHP=mapHPVisitPlan.get(objCP.HospitalId__c);
                if(objHP!=null){//计划已拜访医院
                
                    //医院地址赋值
                    if(HospitalAddress==null||HospitalAddress==''){
                         HospitalAddress=objHP.adress__c;
                    }
    
                    if(objHP.lat__c!=null&&objHP.lon__c!=null){
                        strPlanStatus+='1;';//状态为1
                        strTemp1+=objHP.Lat__c+','+objHP.Lon__c+';';
                        strTemp2+=objHP.Name+';';
                        strTemp9+=string.ValueOf(i)+';';  
                    }
                }else{//计划未拜访医院
                    objHP=mapHPPlanNoVisit.get(objCP.HospitalId__c);
                    
                    //医院地址赋值
                    if(HospitalAddress==null||HospitalAddress==''){
                         HospitalAddress=objHP.adress__c;
                    }
                                        
                    if(objHP!=null){
                        if(objHP.lat__c!=null&&objHP.lon__c!=null){
                            strPlanStatus+='0;';//状态为0
                            strTemp1+=objHP.Lat__c+','+objHP.Lon__c+';';
                            strTemp2+=objHP.Name+';';
                            strTemp9+=string.ValueOf(i)+';';  
                        }                     
                    }
                   
                }          
           }              
       }              
                        
      if(strTemp1!=''&&strTemp1.contains(';')){
          strTemp1=strTemp1.substring(0,strTemp1.length()-1);
      }
      if(strTemp2!=''&&strTemp2.contains(';')){
          strTemp2=strTemp2.substring(0,strTemp2.length()-1);
      }
      if(strTemp3!=''&&strTemp3.contains(';')){
          strTemp3=strTemp3.substring(0,strTemp3.length()-1);
      }
      if(strTemp4!=''&&strTemp4.contains(';')){
          strTemp4=strTemp4.substring(0,strTemp4.length()-1);
      }
      if(strTemp5!=''&&strTemp5.contains(';')){
          strTemp5=strTemp5.substring(0,strTemp5.length()-1);
      }
     if(strTemp6!=''&&strTemp6.contains(';')){
          strTemp6=strTemp6.substring(0,strTemp6.length()-1);
      }
     if(strTemp9!=''&&strTemp9.contains(';')){
          strTemp9=strTemp9.substring(0,strTemp9.length()-1);
      }      
          
      PlanAddress=strTemp1;
      PlanHospitalNames=strTemp2;
      
      VisitAddress=strTemp3;
      VisitHospitalNames=strTemp4;
      ExceptionArray=strTemp5;
      RangeValues=strTemp6;
      PlanOrder=strTemp9;


      
      //生成计划路线状态
      if(strPlanStatus!=''&&strPlanStatus.contains(';')){
          strPlanStatus=strPlanStatus.substring(0,strPlanStatus.length()-1);
      }           
      PlanStatus=strPlanStatus;
      
      }
}